// drawMindMap.js

export function drawMindMap(ctx, node, x, y, depth, offsetX = 0, offsetY = 0, align = "center") {
  if (!node) return
  
      // ========== 样式控制 ==========
      let fontSize = 8
      let fontColor = "#333"
      let borderColor
      let bgColor = "#fff"
      let isBold = false
  
      if (depth === 0) { // 第一层
          fontColor = "#fff"
          borderColor = "#589589"
          bgColor = "#589589"
          isBold = true
      } else if (depth === 1) { // 第二层
          fontColor = "#000"
          borderColor = "#589589"
          bgColor = "#fff"
      } else { // 第三层及以下
          fontColor = "#848485"
      }
  
      // ========== 文本换行 ==========
      const maxWidth = 180  // 如果文字宽度较大，适当增加最大宽度
      const lineHeight = fontSize + 4
      const textLines = breakText(ctx, node.data.text, fontSize, maxWidth)
  
      // ========== 节点背景框 ==========
      const boxPaddingX = 16 // 增加水平内边距，避免文字贴近节点边缘
      const boxPaddingY = 6
      const boxWidth = maxWidth + boxPaddingX * 2
      const boxHeight = textLines.length * lineHeight + boxPaddingY * 2
  
      ctx.beginPath()
      ctx.fillStyle = bgColor
      ctx.strokeStyle = borderColor
      ctx.lineWidth = 1
  
      if (depth < 2) {
          roundRect(ctx, x - boxWidth / 2 + offsetX, y - boxHeight / 2 + offsetY, boxWidth, boxHeight, 6)
          ctx.fill()
          ctx.stroke()
      } else {
          roundRect(ctx, x - boxWidth / 2 + offsetX, y - boxHeight / 2 + offsetY, boxWidth, boxHeight, 6)
          ctx.fill()
      }
  
      // ========== 绘制文字 ==========
      // ctx.font = (isBold ? "bold " : "") + ${fontSize}px 'Alibaba PuHuiTi', Arial;  // 使用阿里巴巴普惠体字体
	  ctx.font = (isBold ? "bold " : "") + `${fontSize}px 'Arial', 'Helvetica', 'sans-serif'`;
	  
      // 调用 drawText 函数处理换行和对齐问题
	  drawText(ctx, textLines, x, y, fontSize, lineHeight, offsetX, offsetY, boxWidth, align, fontColor)
  
      // ========== 绘制子节点 ==========
      if (node.children && node.children.length > 0) {
  
          // 核心修改 ✅ gapX 和 gapY 依赖 boxSize
          const gapX = boxWidth * 2 // 增加水平间距，这里可以适当增大，例如设置为 boxWidth * 2
		  const gapY = 20 // 增加垂直间距，调整子节点之间的空隙
         // 子节点起始 Y
		 let childY = y - node.subtreeHeight / 2
          // const totalHeight = (node.children.length - 1) * gapY
  
          node.children.forEach((child, index) => {
              const childX = x + gapX
               const childCenterY = childY + child.subtreeHeight / 2
  
              // 连线
              ctx.beginPath()
              ctx.moveTo(x + boxWidth / 2 + offsetX, y + offsetY)
              ctx.lineTo(childX - boxWidth / 2 + offsetX, childCenterY + offsetY)
              ctx.strokeStyle = "#589589"
              ctx.stroke()
  
              // 递归
              drawMindMap(ctx, child, childX, childCenterY, depth + 1, offsetX, offsetY, align)
			  // childY 叠加
			  childY += child.subtreeHeight + gapY
          })
      }
}

// ========== 自动换行 ==========
export function breakText(ctx, text, fontSize, maxWidth) {
	ctx.font = `${fontSize}px 'Arial', 'Helvetica', 'sans-serif'`
	const words = text.split("")
	const lines = []
	let line = ""

	for (let i = 0; i < words.length; i++) {
		const testLine = line + words[i]
		const metrics = ctx.measureText(testLine)
		if (metrics.width > maxWidth) {
			lines.push(line)
			line = words[i]
		} else {
			line = testLine
		}
	}
	if (line) lines.push(line)
	return lines
}

// 处理文字模糊的辅助函数
function adjustForDevicePixelRatio(ctx) {
	wx.getDeviceInfo({
		success(res) {
			const dpr = res.pixelRatio || 1;  // Fallback to 1 if pixelRatio is not found
			const canvas = ctx.canvas;
			
			 // 1. 调整画布的显示尺寸
			canvas.style.width = `${canvas.width}px`;
			canvas.style.height = `${canvas.height}px`;
			
			// 2. 调整画布的实际尺寸（像素尺寸）
			canvas.width = canvas.width * dpr;
			canvas.height = canvas.height * dpr;
			
			// 设置上下文的缩放比例，避免模糊
			ctx.scale(dpr, dpr);
		},
		fail() {
			console.error("Failed to get device info.");
		}
	});
}

// 修改绘制文字的对齐方式 
export function drawText(ctx, textLines, x, y, fontSize, lineHeight, offsetX, offsetY, boxWidth, align, fontColor) {
    adjustForDevicePixelRatio(ctx);  // 调整画布和上下文
	
	// 判断是否有换行的情况
	const textAlign = textLines.length > 1 ? "left" : align;  // 如果有多行则左对齐，否则根据传入的对齐方式决定
	ctx.textAlign = textAlign
	ctx.fillStyle = fontColor || "#333";  // 使用传入的字体颜色，默认 #333

	// 设置文字下移的偏移量
    const verticalOffset = 2; // 调整该值以控制文字向下的移动量
	
	// 设置字间距
	const letterSpacing = 1; // 调整字间距，单位为像素
		
	// 绘制每一行的文本
	textLines.forEach((line, i) => {
		const textY = y - (textLines.length - 1) * lineHeight / 2 + i * lineHeight + offsetY + verticalOffset;
		 if (textAlign === "left") {
			let xPos = x + offsetX - boxWidth / 2;
			for (let j = 0; j < line.length; j++) {
				ctx.fillText(line[j], xPos, textY);
				xPos += ctx.measureText(line[j]).width + letterSpacing; // 逐个字符绘制并增加字间距
			}
		} else {
			// 居中对齐的处理
			let totalWidth = 0;
			// 计算总宽度
			for (let j = 0; j < line.length; j++) {
				totalWidth += ctx.measureText(line[j]).width + letterSpacing;
			}
			// 计算起始位置
			let xPos = x + offsetX - totalWidth / 2;
			// 逐个字符绘制并增加字间距
			for (let j = 0; j < line.length; j++) {
				ctx.fillText(line[j], xPos, textY);
				xPos += ctx.measureText(line[j]).width + letterSpacing; // 字间距
			}
		}
	});
}

// ========== 扩展 Canvas 支持圆角矩形 ==========
export function roundRect(ctx, x, y, w, h, r) {
    ctx.moveTo(x + r, y)
    ctx.arcTo(x + w, y, x + w, y + h, r)
    ctx.arcTo(x + w, y + h, x, y + h, r)
    ctx.arcTo(x, y + h, x, y, r)
    ctx.arcTo(x, y, x + w, y, r)
    ctx.closePath()
}

export function computeSubtreeHeight(node, ctx, depth) {
    if (!node) return 0

    let fontSize = depth < 2 ? 10 : 6
    const lineHeight = fontSize + 4
    const textLines = breakText(ctx, node.data.text, fontSize, 200)
    const boxHeight = textLines.length * lineHeight + 6 * 2

    if (!node.children || node.children.length === 0) {
        node.subtreeHeight = boxHeight
    } else {
        const totalChildrenHeight = node.children.reduce((sum, child) => {
            return sum + computeSubtreeHeight(child, ctx, depth + 1) + 20 // 20 可视为子节点之间的最小空隙
        }, 0)
		const gapBetweenChildren = 20 // 基础间距
		const dynamicGap = 10 // 额外可调节

		node.subtreeHeight = totalChildrenHeight + (node.children.length - 1) * dynamicGap

		// 可选：如果 box 比子树大，取 boxHeight
		node.subtreeHeight = Math.max(boxHeight, node.subtreeHeight)
    }
    return node.subtreeHeight
}

export function createDragZoomController(offsetXRef, offsetYRef, scaleRef, render) {
    let isDragging = false
    let lastX = 0
    let lastY = 0
    let lastDistance = 0
	let velocityX = 0  // 拖动速度
	let velocityY = 0  // 拖动速度
	let inertiaTimeoutId = null // 用于平滑惯性动画的请求ID

    function getDistance(touches) {
        const dx = touches[0].clientX - touches[1].clientX
        const dy = touches[0].clientY - touches[1].clientY
        return Math.sqrt(dx * dx + dy * dy)
    }

    function onTouchStart(e) {
        if (e.touches.length === 1) { // 单指拖动
            isDragging = true
            lastX = e.touches[0].clientX
            lastY = e.touches[0].clientY
        } else if (e.touches.length === 2) { // 双指缩放
            isDragging = false
            lastDistance = getDistance(e.touches)
        }
    }
	
	// 使用 throttle 限制每次拖动更新的频率
	function throttle(func, wait) {
	    let lastTime = 0;
	    return function(...args) {
	        const now = Date.now();
	        if (now - lastTime >= wait) {
	            func(...args);
	            lastTime = now;
	        }
	    };
	}
	
	// 在绘制时加入 throttle
	const throttledRender = throttle(render, 30); // 每 30ms 更新一次

    function onTouchMove(e) {
        if (e.touches.length === 1 && isDragging) { // 拖动
            const dx = e.touches[0].clientX - lastX
            const dy = e.touches[0].clientY - lastY
			velocityX = dx // 记录每次拖动的速度
			velocityY = dy // 记录每次拖动的速度
						
            offsetXRef.value += dx
            offsetYRef.value += dy
            lastX = e.touches[0].clientX
            lastY = e.touches[0].clientY
            // render()
			throttledRender()  // 使用限制频率的渲染函数
        } else if (e.touches.length === 2) { // 缩放
            const distance = getDistance(e.touches)
            const delta = distance - lastDistance
            let newScale = scaleRef.value + delta * 0.002
            newScale = Math.max(0.5, Math.min(newScale, 3)) // 缩放限制
            const scaleChange = newScale / scaleRef.value
            
			// 计算触摸点的中点
			const midX = (e.touches[0].clientX + e.touches[1].clientX) / 2
			const midY = (e.touches[0].clientY + e.touches[1].clientY) / 2
	
			// 计算偏移量以确保缩放是以中点为中心
			offsetXRef.value -= (midX - offsetXRef.value) * (scaleChange - 1)
			offsetYRef.value -= (midY - offsetYRef.value) * (scaleChange - 1)
	
			scaleRef.value = newScale
			lastDistance = distance
			// render()
			throttledRender() 
        }
    }

    function onTouchEnd() {
        isDragging = false
		// 启动惯性滚动动画
		// startInertia()
    }
	
	function startInertia() {
		function inertiaStep() {
			if (Math.abs(velocityX) > 0.5 || Math.abs(velocityY) > 0.5) {
				offsetXRef.value += velocityX
				offsetYRef.value += velocityY

				// 模拟惯性减速
				velocityX *= 0.95
				velocityY *= 0.95

				render() // 重绘画布

				// 使用 setTimeout 控制每一帧的间隔，模拟动画效果
				inertiaStep()
			} else {
				// 速度小于阈值，停止惯性滚动
				velocityX = 0
				velocityY = 0
			}
		}

		// 启动惯性动画
		inertiaStep()
	}

    return {
        onTouchStart,
        onTouchMove,
        onTouchEnd
    }
}